#include <QVBoxLayout>
#include <QLabel>
#include <QCheckBox>
#include <QLineEdit>
#include <QStackedWidget>
#include <QFileInfo>
#include <QMouseEvent>
#include <QDebug>

#include "imagegalleryitem.h"


namespace Jcr
{

static inline bool operator>(const QSize& lhs, const QSize& rhs)
{
    return lhs.width() > rhs.width() && lhs.height() > rhs.height();
}

class ImageGalleryItemPrivate
{
public:
    void init();
    void layoutCheckBox();
    void doRename();

    ImageGalleryItem* q_ptr;
    QLabel* imageLabel = nullptr;
    QLabel* nameLabel = nullptr;
    QLineEdit* edit = nullptr;
    QStackedWidget* stackedWidget = nullptr;
    QCheckBox* checkBox = nullptr;
    ImageGalleryItem::State state;
    QString file;
};

void ImageGalleryItemPrivate::init()
{
    imageLabel = new QLabel(q_ptr);
    nameLabel = new QLabel(q_ptr);
    nameLabel->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
    edit = new QLineEdit(q_ptr);
    edit->setClearButtonEnabled(true);

    stackedWidget = new QStackedWidget(q_ptr);
    stackedWidget->addWidget(nameLabel);
    stackedWidget->addWidget(edit);
    stackedWidget->setCurrentWidget(nameLabel);

    checkBox = new QCheckBox(q_ptr);
    checkBox->setVisible(false);

    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(imageLabel);
    layout->addWidget(stackedWidget);
    layout->setSpacing(0);
    q_ptr->setLayout(layout);

    q_ptr->connect(edit, SIGNAL(returnPressed()), q_ptr, SLOT(onEditReturnPressed()));
}

void ImageGalleryItemPrivate::layoutCheckBox()
{
    if (checkBox)
        checkBox->move(QPoint(0, 0));
}

void ImageGalleryItemPrivate::doRename()
{
    const QString newBaseName = edit->text();
    nameLabel->setText(newBaseName);

    QFileInfo fi(file);
    QFile imageFile(file);
    QString newFullPath = QString("%1/%2.%3").arg(fi.canonicalPath()).arg(newBaseName).arg(fi.suffix());
    imageFile.rename(newFullPath);
}

ImageGalleryItem::ImageGalleryItem(QWidget* parent) : QWidget(parent)
{
    d_ptr = new ImageGalleryItemPrivate;
    d_ptr->q_ptr = this;
    d_ptr->init();
}

ImageGalleryItem::ImageGalleryItem(const QString& file, QWidget* parent) : QWidget(parent)
{
    d_ptr = new ImageGalleryItemPrivate;
    d_ptr->q_ptr = this;
    d_ptr->init();

    setFile(file);
}

ImageGalleryItem::~ImageGalleryItem()
{
    delete d_ptr;
}

void ImageGalleryItem::setState(ImageGalleryItem::State state)
{
    if (d_ptr->state != state) {
        d_ptr->state = state;

        if (state == View) {
            d_ptr->checkBox->hide();
            d_ptr->layoutCheckBox();
            d_ptr->stackedWidget->setCurrentWidget(d_ptr->nameLabel);
        } else if (state == Edit){
            d_ptr->checkBox->show();
            d_ptr->edit->setText(d_ptr->nameLabel->text());
            d_ptr->stackedWidget->setCurrentWidget(d_ptr->edit);
            d_ptr->edit->setFocus();
        } else if (state == Select) {
            d_ptr->checkBox->show();
            d_ptr->stackedWidget->setCurrentWidget(d_ptr->nameLabel);
        }
    }
}

ImageGalleryItem::State ImageGalleryItem::state() const
{
    return d_ptr->state;
}

void ImageGalleryItem::setFile(const QString& file)
{
    if (d_ptr->file != file) {
        d_ptr->file = file;

        QPixmap pixmap(file);
        if (pixmap.size() > this->size()) {
            QPixmap scaledPixmap = pixmap.scaled(this->size());
            d_ptr->imageLabel->setPixmap(scaledPixmap);
        } else {
            d_ptr->imageLabel->setPixmap(pixmap);
        }

        QFileInfo fi(file);
        d_ptr->nameLabel->setText(fi.baseName());
    }
}

QString ImageGalleryItem::file() const
{
    return d_ptr->file;
}

bool ImageGalleryItem::rename(const QString& newBaseName)
{
    if (d_ptr->nameLabel->text() == newBaseName)
        return false;

    d_ptr->nameLabel->setText(newBaseName);

    QFile f(d_ptr->file);
    QFileInfo fi(d_ptr->file);
    QString newFullName;
    newFullName = QString("%1/%2.%3").arg(fi.canonicalPath()).arg(newBaseName).arg(fi.completeSuffix());
    qDebug() << "new full name: " << newFullName;
    return f.rename(newFullName);
}

QString ImageGalleryItem::baseName() const
{
    QFileInfo fi(d_ptr->file);
    return fi.baseName();
}

void ImageGalleryItem::select(bool select)
{
    d_ptr->checkBox->setChecked(select);
}

bool ImageGalleryItem::selected() const
{
    return d_ptr->checkBox->isVisible() && d_ptr->checkBox->checkState() == Qt::Checked;
}

void ImageGalleryItem::showEvent(QShowEvent *e)
{
    d_ptr->layoutCheckBox();
    QWidget::showEvent(e);
}

void ImageGalleryItem::resizeEvent(QResizeEvent* e)
{
    d_ptr->layoutCheckBox();
    QWidget::resizeEvent(e);
}

void ImageGalleryItem::mouseDoubleClickEvent(QMouseEvent* e)
{
    if (e->buttons() & Qt::LeftButton) {
        if (this->state() == View)
            setState(Edit);
        else
            setState(View);
    }
}

void ImageGalleryItem::onEditReturnPressed()
{
    // rename file
    d_ptr->doRename();

    // change state
    setState(View);
}

} // namespace jcr
